#include "NamedDataBase.h"
#include <f32file.h> //RFs
#include <d32dbms.h>  //RDbNamedDatabase,RDbView
#include <bautils.h>  
#include "aknnotewrappers.h"
#include <s32stor.h>

RDbNamedDatabase gbldb;
	RFs FsSession;
//Destructor of the CMyDBClass
CMyDBClass::~CMyDBClass()
	{
	gbldb.Close();
	iFsSession.Close();
	}
/*
 * A Creates the database session and check for the existing database.
 */
void CMyDBClass::ConstructL()
	{

	RFs FsSession;
	RDbNamedDatabase Database;
	
	
	TRAPD(cr_error, FsSession.Connect());
	// if database exists open it for connections
	if (BaflUtils::FileExists(FsSession, KtxDatabaseName))
		{
		User::LeaveIfError(Database.Open(FsSession, KtxDatabaseName));
		gbldb=Database;
		}
	else
		{ 
	    // if no database exists create a new one
		User::LeaveIfError(Database.Create(FsSession, KtxDatabaseName));
		CreateTableL(Database);
		gbldb=Database;
		}
	}

/*
 * A method to create the table when the database is newly created
 */
void CMyDBClass::CreateTableL(RDbDatabase& aDatabase)
	{
	// Create a table definition
	CDbColSet* columns = CDbColSet::NewLC();
	// Add Columns
	TDbCol id(NCol0,EDbColInt32);
	// Unique inxdex that will auto increment
	id.iAttributes = id.EAutoIncrement;
	columns->AddL(id);

	columns->AddL(TDbCol(NCol1,EDbColText,100));	// My Phone Number
	columns->AddL(TDbCol(NCol2,EDbColText,100));	// Phone number of Remote party
	columns->AddL(TDbCol(NCol3,EDbColText,9));		// Start Time
	columns->AddL(TDbCol(NCol4,EDbColText,2));		// Direction (Incoming OR Outgoing)
	columns->AddL(TDbCol(NCol5,EDbColText,2));		// Type (Voice OR Video)
	//columns->AddL(TDbCol(NCol6,EDbColText,100));	// Duration in seconds
	columns->AddL(TDbCol(NCol6,EDbColUint32));		// Duration in seconds
	columns->AddL(TDbCol(NCol7,EDbColText,11));		// Date
	
	TInt cr_error=aDatabase.CreateTable(KtxtLogTable,*columns);
	CleanupStack::PopAndDestroy(columns);
	}
void CMyDBClass::SaveToDatabaseL(const TDesC& myNumber, 
								 const TDesC& aRemoteNumber, 
								 const TDesC& aStartTime, 
								 const TDesC& aDirection, 
								 const TDesC& aType, 
								 const TUint32& aDuration, 
								 const TDesC& aDate)
	{

	         //Open the database connection
	        ConstructL();
	        TFileName QueryBuffer;
	    	QueryBuffer.Copy(_L("SELECT * FROM "));
	    	QueryBuffer.Append(KtxtLogTable);
	    	gbldb.Begin();
	    	RDbView Myview;
	    	Myview.Prepare(gbldb, TDbQuery(QueryBuffer));
	    	CleanupClosePushL(Myview);
	     
	    	Myview.InsertL(); 
	    //	aIndex = Myview.ColInt(1);
	    	Myview.SetColL(2, myNumber);
	    	Myview.SetColL(3, aRemoteNumber);
	    	Myview.SetColL(4, aStartTime);
	    	Myview.SetColL(5, aDirection);
	    	Myview.SetColL(6, aType);
	    	Myview.SetColL(7, aDuration);
	    	Myview.SetColL(8, aDate);
	    	Myview.PutL();  
	     
	    	// autoincrement gives us unique index.
	     
	    	CleanupStack::PopAndDestroy(1); // Myview
	    	gbldb.Commit();
	    	gbldb.Close();
	    	FsSession.Close();	
	}

void CMyDBClass::ReadDbItemsL(RArray<TExampleItem>& aItemArray)
{
	ConstructL();
	aItemArray.Reset();// first reset the array
 
	TFileName QueryBuffer;
	// just get all columns & rows
	QueryBuffer.Copy(_L("SELECT * FROM "));
	QueryBuffer.Append(KtxtLogTable);
 
	RDbView Myview;
	Myview.Prepare(gbldb,TDbQuery(QueryBuffer));
	CleanupClosePushL(Myview);
	Myview.EvaluateAll();
	Myview.FirstL();
 
	// Just delete one instance of the message
	while(Myview.AtRow()) 
	{	
		Myview.GetL();		
 
		TExampleItem NewItem;	
		NewItem.iIndex = Myview.ColInt(1);
        NewItem.iMyNumber.Copy(Myview.ColDes(2));
       // NewItem.iValue.Copy(Myview.ColDes(3));
 
		aItemArray.Append(NewItem);		
		Myview.NextL();
	} 
 
	CleanupStack::PopAndDestroy(1); // Myview
	gbldb.Close();
    FsSession.Close();
}

void CMyDBClass::DeleteFromDatabaseL(const TDesC& afromDate, const TDesC& atoDate)
{
	ConstructL();
	TFileName QueryBuffer;
	QueryBuffer.Copy(_L("SELECT * FROM "));
	QueryBuffer.Append(KtxtLogTable);		
	gbldb.Begin();
	RDbView Myview;
	// query buffr with index finds only the selected item row.
	Myview.Prepare(gbldb, TDbQuery(QueryBuffer));
	CleanupClosePushL(Myview);
	
	QueryBuffer.Copy(_L("DELETE * FROM "));	// Starting a new String. NOTE: Copy() function used
	QueryBuffer.Append(KtxtLogTable);	
	QueryBuffer.Append(_L(" WHERE "));
	QueryBuffer.Append(NCol7);
	QueryBuffer.Append(_L(" BETWEEN '"));
	QueryBuffer.Append(afromDate);
	QueryBuffer.Append(_L("' AND '"));
	QueryBuffer.Append(atoDate);
	QueryBuffer.Append(_L("'"));
	
	TInt errCode = Myview.EvaluateAll();

	Myview.FirstL();
	// we have autoincrement in index so it should be unique
	// but just to make sure, we use 'while', instead of 'if'
	while (Myview.AtRow())
		{
		Myview.GetL();
		Myview.DeleteL();
		Myview.NextL();
		}

	CleanupStack::PopAndDestroy(1); // Myview
	gbldb.Commit();
	// compacts the databse, by physicaly removig deleted data.
	gbldb.Compact();
	gbldb.Close();
	FsSession.Close();

}

void CMyDBClass::UpdateDatabaseL(const TDesC& aName, const TDesC& aValue,
		TInt& aIndex)
	{
	TFileName QueryBuffer;
	QueryBuffer.Copy(_L("SELECT * FROM "));
	QueryBuffer.Append(KtxtLogTable);
	QueryBuffer.Append(_L(" WHERE "));
	QueryBuffer.Append(NCol0);
	QueryBuffer.Append(_L(" = "));
	QueryBuffer.AppendNum(aIndex);

	gbldb.Begin();

	RDbView Myview;
	Myview.Prepare(gbldb, TDbQuery(QueryBuffer));
	CleanupClosePushL(Myview);

	Myview.EvaluateAll();
	Myview.FirstL();

	if (Myview.AtRow())
		{
		Myview.UpdateL();
		Myview.SetColL(2, aName);
		Myview.SetColL(3, aValue);
		Myview.PutL();
		}

	CleanupStack::PopAndDestroy(1); // Myview
	gbldb.Commit();
	}

/*
 * Get the details of the report for a given data period
 */
RArray<TExampleItem>CMyDBClass::GetDetailsFromDatabaseL(const TDesC& afromDate, const TDesC& atoDate)
{
	    RArray<TExampleItem> aItemArray;
	    aItemArray.Reset();// first reset the array
		ConstructL();
		TFileName QueryBuffer;
		QueryBuffer.Copy(_L("SELECT * FROM "));
		QueryBuffer.Append(KtxtLogTable);		
		gbldb.Begin();
		RDbView Myview;
		// query buffr with index finds only the selected item row.
		Myview.Prepare(gbldb, TDbQuery(QueryBuffer));
		CleanupClosePushL(Myview);
		
		QueryBuffer.Copy(_L("SELECT * FROM "));	// Starting a new String. NOTE: Copy() function used
		QueryBuffer.Append(KtxtLogTable);	
		QueryBuffer.Append(_L(" WHERE "));
		QueryBuffer.Append(NCol7);
		QueryBuffer.Append(_L(" BETWEEN '"));
		QueryBuffer.Append(afromDate);
		QueryBuffer.Append(_L("' AND '"));
		QueryBuffer.Append(atoDate);
		QueryBuffer.Append(_L("'"));
		
		TInt errCode = Myview.EvaluateAll();
		Myview.FirstL();

		// Just delete one instance of the message
		while(Myview.AtRow()) 
		   { 
		    Myview.GetL();  
		   
		    TExampleItem NewItem; 
		    NewItem.iIndex = Myview.ColInt(1);
		    NewItem.iMyNumber.Copy(Myview.ColDes(2));
		    NewItem.iRemoteNumber.Copy(Myview.ColDes(3));
		    NewItem.iStartTime.Copy(Myview.ColDes(4));
		    NewItem.iDirection.Copy(Myview.ColDes(5));
		    NewItem.iType.Copy(Myview.ColDes(6));
		    NewItem.iDuration=Myview.ColUint32(7);
		    NewItem.iDate.Copy(Myview.ColDes(8));
		    aItemArray.Append(NewItem);  
		    Myview.NextL();
		   }
	 
		CleanupStack::PopAndDestroy(1); // Myview
		gbldb.Close();
	    FsSession.Close();
	    return aItemArray;
}


